"""
构建脚本 - 用于创建可执行文件
"""
import os
import sys
import subprocess
import shutil
import PySide6

def check_and_fix_environment():
    """检查和修复Python环境问题"""
    try:
        # 检查是否存在问题的typing包
        import pkg_resources

        # 获取已安装的包
        installed_packages = [d.project_name for d in pkg_resources.working_set]

        if 'typing' in installed_packages:
            print("⚠️  检测到过时的'typing'包，这会导致PyInstaller失败")
            print("正在尝试移除...")

            # 尝试使用conda移除
            try:
                result = subprocess.run(['conda', 'remove', 'typing', '-y'],
                                      capture_output=True, text=True, timeout=30)
                if result.returncode == 0:
                    print("✅ 成功使用conda移除typing包")
                else:
                    print("⚠️  conda移除失败，尝试使用pip...")
                    # 尝试使用pip移除
                    result = subprocess.run(['pip', 'uninstall', 'typing', '-y'],
                                          capture_output=True, text=True, timeout=30)
                    if result.returncode == 0:
                        print("✅ 成功使用pip移除typing包")
                    else:
                        print("❌ 无法自动移除typing包")
                        print("请手动执行以下命令之一：")
                        print("  conda remove typing")
                        print("  pip uninstall typing")
                        return False
            except subprocess.TimeoutExpired:
                print("❌ 移除typing包超时")
                return False
            except FileNotFoundError:
                print("⚠️  未找到conda，尝试使用pip...")
                try:
                    result = subprocess.run(['pip', 'uninstall', 'typing', '-y'],
                                          capture_output=True, text=True, timeout=30)
                    if result.returncode == 0:
                        print("✅ 成功使用pip移除typing包")
                    else:
                        print("❌ pip移除失败")
                        return False
                except Exception as e:
                    print(f"❌ 移除typing包失败: {e}")
                    return False

        # 检查必要的依赖
        required_packages = ['PySide6', 'pynput', 'psutil', 'pyinstaller']
        missing_packages = []

        for package in required_packages:
            try:
                __import__(package.lower().replace('-', '_'))
            except ImportError:
                missing_packages.append(package)

        if missing_packages:
            print(f"缺少必要的包: {', '.join(missing_packages)}")
            print("请先安装缺少的包：")
            print(f"  pip install {' '.join(missing_packages)}")
            return False

        print("Python环境检查通过")
        return True

    except Exception as e:
        print(f"环境检查失败: {e}")
        return False

def install_missing_dependencies():
    """安装缺少的依赖"""
    print("正在安装/更新依赖...")

    try:
        # 升级pip
        subprocess.run([sys.executable, '-m', 'pip', 'install', '--upgrade', 'pip'],
                      check=True, capture_output=True)

        # 安装依赖
        subprocess.run([sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt'],
                      check=True, capture_output=True)

        # 安装PyInstaller
        subprocess.run([sys.executable, '-m', 'pip', 'install', 'pyinstaller'],
                      check=True, capture_output=True)

        print("✅ 依赖安装完成")
        return True

    except subprocess.CalledProcessError as e:
        print(f"❌ 依赖安装失败: {e}")
        return False

def create_spec_file():
    """创建自定义的spec文件以更好地控制构建过程"""
    spec_content = '''# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
    ['main.py'],
    pathex=[],
    binaries=[],
    datas=[('requirements.txt', '.')],
    hiddenimports=[
        'pynput.keyboard._win32',
        'pynput.mouse._win32', 
        'win32gui',
        'win32process',
        'psutil',
        'PySide6.QtCore',
        'PySide6.QtGui', 
        'PySide6.QtWidgets',
    ],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=['typing'],  # 明确排除typing包
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='WorkMonitor',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon='icon.ico' if os.path.exists('icon.ico') else None,
)
'''

    with open('WorkMonitor.spec', 'w', encoding='utf-8') as f:
        f.write(spec_content)

    print("✅ 已创建自定义spec文件")

def build_with_spec():
    """使用spec文件构建"""
    try:
        create_spec_file()

        cmd = ["pyinstaller", "--noconfirm", "WorkMonitor.spec"]

        print("使用spec文件构建...")
        result = subprocess.run(cmd, check=True, capture_output=True, text=True)
        print("✅ 构建成功！")
        print(f"可执行文件位置: dist/WorkMonitor{'.exe' if sys.platform == 'win32' else ''}")
        return True

    except subprocess.CalledProcessError as e:
        print(f"❌ spec文件构建失败: {e}")
        print(f"错误输出: {e.stderr}")
        return False

def build_executable():
    """使用 PyInstaller 构建可执行文件"""

    print("开始构建可执行文件...")

    # 检查和修复环境问题
    print("检查Python环境...")
    if not check_and_fix_environment():
        return False

    # PyInstaller 命令
    cmd = [
        "pyinstaller",
        "--onefile",           # 单文件模式
        "--windowed",          # 无控制台窗口
        "--name=WorkMonitor",  # 可执行文件名
        "--add-data=requirements.txt;." if sys.platform == "win32" else "--add-data=requirements.txt:.",  # 包含依赖文件
        "--hidden-import=pynput.keyboard._win32",  # 添加隐藏导入
        "--hidden-import=pynput.mouse._win32",
        "--hidden-import=win32gui",
        "--hidden-import=win32process",
        "--hidden-import=psutil",
        "--collect-all=PySide6",  # 收集所有PySide6模块
        "--noconfirm",  # 不询问覆盖
        "main.py"
    ]

    # 如果有图标文件则添加
    if os.path.exists("icon.ico"):
        cmd.insert(-1, "--icon=icon.ico")

    try:
        # 执行构建
        result = subprocess.run(cmd, check=True, capture_output=True, text=True)
        print("✅ 构建成功！")
        print(f"可执行文件位置: dist/WorkMonitor{'.exe' if sys.platform == 'win32' else ''}")

    except subprocess.CalledProcessError as e:
        print(f"❌ 构建失败: {e}")
        print(f"错误输出: {e.stderr}")

        # 如果是typing包问题，尝试使用spec文件构建
        if 'typing' in e.stderr:
            print("🔄 检测到typing包问题，尝试使用spec文件构建...")
            return build_with_spec()

        return False

    except FileNotFoundError:
        print("❌ 错误: 未找到 PyInstaller")
        print("请先安装: pip install pyinstaller")

        # 尝试自动安装
        if install_missing_dependencies():
            print("🔄 重新尝试构建...")
            return build_executable()

        return False

    return True

def create_installer():
    """创建安装包（Windows）"""
    if sys.platform != "win32":
        print("安装包创建仅支持 Windows")
        return

    try:
        # 使用 NSIS 或 Inno Setup 创建安装包
        print("创建 Windows 安装包...")
        # 这里可以添加 NSIS 脚本调用

    except Exception as e:
        print(f"创建安装包失败: {e}")

def clean_build():
    """清理构建文件"""
    dirs_to_clean = ["build", "dist", "__pycache__"]
    files_to_clean = ["*.spec"]

    for dir_name in dirs_to_clean:
        if os.path.exists(dir_name):
            shutil.rmtree(dir_name)
            print(f"已删除: {dir_name}")

    import glob
    for pattern in files_to_clean:
        for file in glob.glob(pattern):
            os.remove(file)
            print(f"已删除: {file}")

def configure_autostart():
    """配置程序开机自启动"""
    print("配置开机自启动...")

    if sys.platform == "win32":
        # Windows 系统
        try:
            import winreg

            # 获取当前用户启动文件夹路径
            startup_path = os.path.join(os.getenv('APPDATA'), 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup')

            # 创建快捷方式
            exe_path = os.path.join(os.getcwd(), 'dist', 'WorkMonitor.exe')
            shortcut_path = os.path.join(startup_path, 'WorkMonitor.lnk')

            # 使用 Python 创建快捷方式
            import winshell
            from win32com.client import Dispatch

            shell = Dispatch('WScript.Shell')
            shortcut = shell.CreateShortCut(shortcut_path)
            shortcut.Targetpath = exe_path
            shortcut.WorkingDirectory = os.path.dirname(exe_path)
            shortcut.save()

            print(f"✅ 已创建开机自启动快捷方式: {shortcut_path}")
            return True

        except Exception as e:
            print(f"❌ Windows 开机自启动配置失败: {e}")
            return False

    elif sys.platform == "linux":
        # Linux 系统
        try:
            # 创建 systemd 服务文件
            service_content = f"""[Unit]
Description=Work Monitor Service
After=network.target

[Service]
Type=simple
ExecStart={os.path.join(os.getcwd(), 'dist', 'WorkMonitor')}
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
"""

            service_path = "/etc/systemd/system/work-monitor.service"

            # 需要 root 权限写入
            with open(service_path, 'w') as f:
                f.write(service_content)

            # 启用服务
            subprocess.run(['sudo', 'systemctl', 'daemon-reload'], check=True)
            subprocess.run(['sudo', 'systemctl', 'enable', 'work-monitor.service'], check=True)

            print("✅ 已创建 systemd 服务并启用开机自启动")
            return True

        except Exception as e:
            print(f"❌ Linux 开机自启动配置失败: {e}")
            return False

    elif sys.platform == "darwin":
        # macOS 系统
        try:
            # 创建 LaunchAgent plist 文件
            plist_content = f"""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.example.workmonitor</string>
    <key>ProgramArguments</key>
    <array>
        <string>{os.path.join(os.getcwd(), 'dist', 'WorkMonitor')}</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
"""

            plist_path = os.path.expanduser("~/Library/LaunchAgents/com.example.workmonitor.plist")

            with open(plist_path, 'w') as f:
                f.write(plist_content)

            print(f"✅ 已创建 LaunchAgent plist 文件: {plist_path}")
            return True

        except Exception as e:
            print(f"❌ macOS 开机自启动配置失败: {e}")
            return False

    else:
        print(f"❌ 不支持的操作系统: {sys.platform}")
        return False

if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(description="构建工作量监控应用")
    parser.add_argument("--clean", action="store_true", help="清理构建文件")
    parser.add_argument("--installer", action="store_true", help="创建安装包")
    parser.add_argument("--fix-env", action="store_true", help="修复Python环境问题")
    parser.add_argument("--spec", action="store_true", help="使用spec文件构建")
    parser.add_argument("--autostart", action="store_true", help="配置开机自启动")

    args = parser.parse_args()

    if args.clean:
        clean_build()
    elif args.fix_env:
        check_and_fix_environment()
    elif args.spec:
        build_with_spec()
    else:
        if build_executable():
            if args.installer:
                create_installer()
            if args.autostart:
                configure_autostart()